home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / misc / ADView.lha / Autodoc / Autodoc.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  11KB  |  505 lines

  1. //
  2. // Autodoc.c by Jean-Guy Speton.  Last updated: May 2, 1995.
  3. //
  4. // This program uses triton.library Copyright © Stefan Zeiger.
  5. //
  6. // This program was developed using DICE 3.0.  Changed may be needed
  7. // for this program to compile under another C compiler.  Most notably,
  8. // your compiler probably lacks the GetSucc() and GetHead() functions
  9. // which DICE defines in <lists.h>.
  10. //
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <lists.h>
  16. #include <signal.h>
  17.  
  18. #include <dos/dos.h>
  19. #include <dos/exall.h>
  20. #include <exec/lists.h>
  21. #include <exec/memory.h>
  22. #include <libraries/triton.h>
  23.  
  24. #include <clib/alib_protos.h>
  25. #include <clib/exec_protos.h>
  26. #include <clib/dos_protos.h>
  27. #include <clib/triton_protos.h>
  28.  
  29. #include <pragmas/triton_pragmas.h>
  30.  
  31. const char version_string[] = "\0$VER: AutodocViewer 1.0 (02-May-95)";
  32.  
  33. /// Function prototypes.
  34.  
  35. void BreakFunction(int code);
  36. void do_main(void);
  37. void DispatchAutodoc(STRPTR docname, struct Project *p);
  38. void DispatchEntry(BPTR file_handle, struct Project *p, ULONG count, STRPTR name);
  39. struct Node *AllocNode(STRPTR name);
  40. void FreeProject(struct Project *p);
  41. struct Project *AllocProject(ULONG id);
  42. STRPTR ReadLine(BPTR file, STRPTR buf, ULONG len);
  43.  
  44. //// Globals.
  45.  
  46. struct Library *TritonBase;
  47. struct TR_App *app;
  48. struct ExAllControl *eac;
  49. struct ExAllData *ead;
  50. UBYTE EAData[1024];
  51. BPTR lock, oldlock;
  52. struct List doc_list, proj_list;
  53. struct TR_Project *main_proj;
  54.  
  55. //// Structure definitions.
  56.  
  57. struct Project {
  58.     struct Project        *proj_Succ, *proj_Pred;
  59.     struct TR_Project    *proj_TRProject;
  60.     BPTR                proj_File;                // File handle for this autodoc.
  61.     ULONG                proj_ID;
  62.     struct List            proj_List;
  63. };
  64.  
  65. /////////////////////////////////////////////////////////////////////
  66.  
  67. int main(void)
  68. {
  69.     signal(SIGINT, SIG_IGN);    // We'll handle CTRL-C's ourselves.
  70.  
  71.     NewList(&doc_list);
  72.     NewList(&proj_list);
  73.  
  74.     if (TritonBase = OpenLibrary(TRITONNAME, TRITON12VERSION)) {
  75.  
  76.         if (app = TR_CreateAppTags(
  77.                         TRCA_Name,        "ADView",
  78.                         TRCA_LongName,    "Autodoc View",
  79.                         TRCA_Info,        "Point-and-click autodoc viewer.",
  80.                         TRCA_Version,    "1.0",
  81.                         TRCA_Release,    "1",
  82.                         TRCA_Date,        "2.5.95",
  83.                     TAG_END)) {
  84.             do_main();
  85.         }
  86.         else
  87.             PutStr("Couldn't create triton application.\n");
  88.     }
  89.     else
  90.         PutStr("Can't open triton.library v2+.\n");
  91.  
  92.     BreakFunction(20);
  93. }
  94.  
  95. void BreakFunction(int code)
  96. {
  97.     struct Node *n;
  98.     struct Project *p;
  99.  
  100.     // Clean up any still-open windows before shutting down.
  101.  
  102.     if (main_proj) {
  103.         while (p = GetHead(&proj_list)) {
  104.             Remove((struct Node *)p);
  105.             FreeProject(p);
  106.         }
  107.  
  108.         TR_CloseProject(main_proj);
  109.  
  110.         while (n = GetHead(&doc_list)) {
  111.             Remove(n);
  112.             FreeVec(n);
  113.         }
  114.     }
  115.  
  116.     if (eac)
  117.         FreeDosObject(DOS_EXALLCONTROL, eac);
  118.  
  119.     if (oldlock)
  120.         CurrentDir(oldlock);
  121.  
  122.     if (lock)
  123.         UnLock(lock);
  124.  
  125.     if (app)
  126.         TR_DeleteApp(app);
  127.  
  128.     if (TritonBase)
  129.         CloseLibrary(TritonBase);
  130.  
  131.     exit(code);
  132. }
  133.  
  134. void do_main(void)
  135. {
  136.     BOOL more;
  137.     ULONG id_count = 1;
  138.  
  139.     struct Node *n, *n2;
  140.     struct Project *p;
  141.  
  142.     struct TR_Message *trmsg;
  143.  
  144.     if (!(lock = Lock("AUTODOC:", ACCESS_READ))) {
  145.         PutStr("Lock on AUTODOC: failed.\n");
  146.         return;
  147.     }
  148.  
  149.     if (!(eac = (struct ExAllControl *) AllocDosObject(DOS_EXALLCONTROL, NULL))) {
  150.         PutStr("AllocDosObject() failed.\n");
  151.         UnLock(lock);
  152.         return;
  153.     }
  154.  
  155.     eac->eac_LastKey = 0;
  156.     eac->eac_MatchString = NULL;
  157.     eac->eac_MatchFunc = NULL;
  158.  
  159.     oldlock = CurrentDir(lock);
  160.  
  161.     // Build the list of autodoc files.
  162.  
  163.     do {
  164.         more = ExAll(lock, EAData, sizeof(EAData), ED_NAME, eac);
  165.         if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES)) {
  166.  
  167.             // ExAll failed abnormally.
  168.  
  169.             break;
  170.         }
  171.         if (eac->eac_Entries == 0)
  172.             break;
  173.  
  174.         ead = (struct ExAllData *) EAData;
  175.         do {
  176.             if (!stricmp(".doc", &ead->ed_Name[strlen(ead->ed_Name) - 4])) {
  177.  
  178.                 // Autodoc entry, add name to listview.
  179.  
  180.                 if (n = AllocNode(ead->ed_Name)) {
  181.  
  182.                     n2 = GetHead(&doc_list);
  183.                     if (strcmp(n->ln_Name, n2->ln_Name) < 0)
  184.                         AddHead(&doc_list, n);
  185.                     else {
  186.                         while (n2) {
  187.                             if (n2->ln_Succ) {
  188.                                 if (strcmp(n->ln_Name, n2->ln_Succ->ln_Name) < 0) {
  189.                                     Insert(&doc_list, n, n2);
  190.                                     break;
  191.                                 }
  192.                             }
  193.                             n2 = GetSucc(n2);
  194.                         }
  195.                         if (!n2)
  196.                             AddTail(&doc_list, n);
  197.                     }
  198.                 }
  199.             }
  200.             ead = ead->ed_Next;
  201.         } while (ead);
  202.     } while (more);
  203.  
  204.  
  205.     // We now enter our main event loop.
  206.  
  207.     if (main_proj = TR_OpenProjectTags(app,
  208.                                 TRWI_Title,        "ADView",
  209.                                 TRWI_Position,    TRWP_DEFAULT,
  210.                                 TRWI_ID,        1,
  211.  
  212.                                 VertGroupA,
  213.                                     Space,
  214.                                     HorizGroupA,
  215.                                         Space,
  216.                                         NamedSeparatorN("Autodoc Reader"),
  217.                                         Space,
  218.                                     EndGroup,
  219.                                     Space,
  220.                                     HorizGroupA,
  221.                                         Space,
  222.                                         TROB_Listview,    &doc_list,
  223.                                             TRAT_ID,    1,
  224.                                             TRAT_Flags,    TRLV_SELECT,
  225.                                         Space,
  226.                                     EndGroup,
  227.                                     Space,
  228.                                 EndGroup,
  229.                             TAG_END)) {
  230.  
  231.         while (1) {
  232.  
  233.             ULONG sigs;
  234.  
  235.             sigs = TR_Wait(app, SIGBREAKF_CTRL_C);
  236.  
  237.             if (sigs & SIGBREAKF_CTRL_C)
  238.                 BreakFunction(0);
  239.  
  240.             while (trmsg = TR_GetMsg(app)) {
  241.  
  242.                 switch(trmsg->trm_Class) {
  243.  
  244.                     case TRMS_NEWVALUE:
  245.                         if (trmsg->trm_Project == main_proj) {
  246.                             n = GetHead(&doc_list);
  247.                             while (trmsg->trm_Data--)
  248.                                 n = GetSucc(n);
  249.                             if (p = AllocProject(++id_count)) {
  250.                                 DispatchAutodoc(n->ln_Name, p);
  251.                                 if (p->proj_TRProject)
  252.                                     AddTail(&proj_list, (struct Node *)p);
  253.                                 else
  254.                                     FreeProject(p);
  255.                             }
  256.                         }
  257.                         else {
  258.                             p = GetHead(&proj_list);
  259.                             while (p) {
  260.                                 if (p->proj_TRProject == trmsg->trm_Project) {
  261.                                     struct Project *new_p;
  262.                                     if (new_p = AllocProject(++id_count)) {
  263.  
  264.                                         UBYTE *name, count = trmsg->trm_Data;
  265.  
  266.                                         n = GetHead(&p->proj_List);
  267.                                         while (n) {
  268.                                             if (count-- == 0) {
  269.                                                 name = n->ln_Name;
  270.                                                 break;
  271.                                             }
  272.                                             n = GetSucc(n);
  273.                                         }
  274.  
  275.                                         DispatchEntry(p->proj_File, new_p, trmsg->trm_Data, name);
  276.                                         if (p->proj_TRProject) {
  277.                                             AddTail(&proj_list, (struct Node *)new_p);
  278.                                         }
  279.                                         else
  280.                                             FreeProject(p);
  281.                                     }
  282.                                     break;
  283.                                 }
  284.                                 p = GetSucc(p);
  285.                             }
  286.                         }
  287.                         break;
  288.  
  289.                     case TRMS_CLOSEWINDOW:
  290.                         if (trmsg->trm_Project == main_proj)
  291.                             BreakFunction(0);
  292.                         else {
  293.                             p = GetHead(&proj_list);
  294.                             while (p) {
  295.                                 if (p->proj_TRProject == trmsg->trm_Project) {
  296.                                     Remove((struct Node *)p);
  297.                                     FreeProject(p);
  298.                                     break;
  299.                                 }
  300.                                 p = GetSucc(p);
  301.                             }
  302.                         }
  303.                         break;
  304.  
  305.                     case TRMS_ERROR:
  306.                         PutStr(TR_GetErrorString(trmsg->trm_Data));
  307.                         break;
  308.                 }
  309.                 TR_ReplyMsg(trmsg);
  310.             }
  311.         }
  312.     }
  313. }
  314.  
  315. void DispatchAutodoc(STRPTR docname, struct Project *p)
  316. {
  317.     struct Node *entry;
  318.     UBYTE buf[256];
  319.  
  320.     if (p->proj_File = Open(docname, MODE_OLDFILE)) {
  321.         do {
  322.             ReadLine(p->proj_File, buf, 255);
  323.         } while(buf[0] == '\0');
  324.  
  325.         if (!strcmp(buf, "TABLE OF CONTENTS")) {
  326.  
  327.             while (ReadLine(p->proj_File, buf, 255)) {
  328.                 if (buf[0] == 12)    // CTRL-L, first entry starts here.
  329.                     break;
  330.  
  331.                 if (buf[0])
  332.                     if (entry = AllocNode(buf))
  333.                         AddTail(&p->proj_List, (struct Node *)entry);
  334.             }
  335.  
  336.             if (!(p->proj_TRProject = TR_OpenProjectTags(app,
  337.                                         TRWI_Title,        "Contents",
  338.                                         TRWI_Underscore,"~",
  339.                                         TRWI_Position,    TRWP_CENTERDISPLAY,
  340.                                         TRWI_ID,        2,
  341.  
  342.                                         VertGroupA,
  343.                                             Space,
  344.                                             HorizGroupA,
  345.                                                 Space, NamedSeparatorN(docname), Space,
  346.                                             EndGroup,
  347.                                             Space,
  348.                                             HorizGroupA,
  349.                                                 Space,
  350.                                                 TROB_Listview,        &p->proj_List,
  351.                                                     TRAT_Flags,        TRLV_SELECT,
  352.                                                 Space,
  353.                                             EndGroup,
  354.                                             Space,
  355.                                         EndGroup,
  356.                                     TAG_END)))
  357.                 TR_EasyRequestTags(app, "Could not open project window.", "Ok", TAG_END);
  358.         }
  359.         else
  360.             TR_EasyRequest(app, "This is not an autodoc file!", "Ok", TAG_END);
  361.     }
  362.     else
  363.         TR_EasyRequest(app, "Error opening file.", "Ok", TAG_END);
  364. }
  365.  
  366. void DispatchEntry(BPTR file_handle, struct Project *p, ULONG count, STRPTR name)
  367. {
  368.     UBYTE ch, buf[256];
  369.     ULONG oldpos, len = strlen(name);
  370.     BOOL success = FALSE;
  371.     struct Node *line;
  372.  
  373.     if (Seek(file_handle, 0L, OFFSET_BEGINNING) == -1)
  374.         return;
  375.  
  376.     do {
  377.         // Skip to next CTRL-L (12).
  378.  
  379.         do {
  380.             ch = FGetC(file_handle);
  381.             if (ch == -1) return;        // Unexpected EOF.
  382.         } while(ch != 12);
  383.  
  384.         // We want the start of this entry in case we have to
  385.         // go back to its beginning.
  386.  
  387.         oldpos = Seek(file_handle, 0, OFFSET_CURRENT);
  388.  
  389.         // It's possible the entry starts with a/some blank line(s).
  390.  
  391.         do {
  392.             ReadLine(file_handle, buf, 255);
  393.         } while(buf[0] == '\0');
  394.  
  395.         // Check lines against name until we reach a blank line or match.
  396.  
  397.         do {
  398.             if (buf[0]) {
  399.                 if (!strncmp(name, buf, len))
  400.                     success = TRUE;
  401.             }
  402.             else
  403.                 break;
  404.  
  405.             ReadLine(file_handle, buf, 255);
  406.         } while(!success);
  407.  
  408.         if (success) {    // We matched on this entry.
  409.             Seek(file_handle, oldpos, OFFSET_BEGINNING);
  410.             while (ReadLine(file_handle, buf, 255)) {
  411.                 if (buf[0] == 12)
  412.                     break;
  413.                 if (line = AllocNode(buf))
  414.                     AddTail(&p->proj_List, line);
  415.             }
  416.         }
  417.     } while(!success);
  418.  
  419.     // We've loaded the autodoc entry, now display it.
  420.  
  421.     if (!(p->proj_TRProject = TR_OpenProjectTags(app,
  422.                                         TRWI_Title,        "Entry",
  423.                                         TRWI_Underscore,"~",
  424.                                         TRWI_Position,    TRWP_CENTERDISPLAY,
  425.                                         TRWI_ID,        3,
  426.  
  427.                                         VertGroupA,
  428.                                             Space,
  429.                                             HorizGroupA,
  430.                                                 Space, NamedSeparatorN(name), Space,
  431.                                             EndGroup,
  432.                                             Space,
  433.                                             HorizGroupA,
  434.                                                 Space,
  435.                                                 TROB_Listview,        &p->proj_List,
  436.                                                     TRAT_Flags,        TRLV_READONLY | TRLV_FWFONT,
  437.                                                 Space,
  438.                                             EndGroup,
  439.                                             Space,
  440.                                         EndGroup,
  441.                                     TAG_END)))
  442.         TR_EasyRequestTags(app, "Could not open project window.", "Ok", TAG_END);
  443. }
  444.  
  445. struct Node *AllocNode(STRPTR name)
  446. {
  447.     struct Node *n;
  448.  
  449.     if (n = (struct Node *) AllocVec(sizeof(struct Node) + strlen(name) + 1, MEMF_CLEAR | MEMF_ANY)) {
  450.         n->ln_Name = (UBYTE *)(n+1);
  451.         strcpy(n->ln_Name, name);
  452.     }
  453.     return n;
  454. }
  455.  
  456. struct Project *AllocProject(ULONG id)
  457. {
  458.     struct Project *p;
  459.  
  460.     if (p = (struct Project *) AllocVec(sizeof(struct Project), MEMF_CLEAR | MEMF_ANY)) {
  461.         p->proj_ID = id;
  462.         NewList(&p->proj_List);
  463.     }
  464.     return p;
  465. }
  466.  
  467. void FreeProject(struct Project *p)
  468. {
  469.     struct Node *n;
  470.  
  471.     if (p->proj_TRProject)
  472.         TR_CloseProject(p->proj_TRProject);
  473.  
  474.     while (n = GetHead(&p->proj_List)) {
  475.         Remove(n);
  476.         FreeVec(n);
  477.     }
  478.  
  479.     if (p->proj_File)
  480.         Close(p->proj_File);
  481.  
  482.     FreeVec(p);
  483. }
  484.  
  485. STRPTR ReadLine(BPTR file, STRPTR buf, ULONG len)
  486. {
  487.     UBYTE ch, *s = buf, i;
  488.  
  489.     while ((ch = FGetC(file)) != -1) {
  490.         if (ch == '\t') {
  491.             for (i = 0; i < 8; i++)
  492.                 *s++ = ' ';
  493.         }
  494.         else if (ch == '\n')
  495.             break;
  496.         else
  497.             *s++ = ch;
  498.     }
  499.     *s = '\0';
  500.  
  501.     if (ch == -1)
  502.         return NULL;
  503.     return buf;
  504. }
  505.